package com.beardedcoder.utils.ui;

import com.beardedcoder.lowPower.activities.Launch;
import com.beardedcoder.utils.UtilScreen;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.GradientDrawable.Orientation;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.beardedcoder.lowPower.R;

/**
 * this class will handle displaying any content we want to hold.
 * By principle anything we add into our actionbar will implement an Action interface, this means
 * that everything passed in is clickable and can return onClick (through the interface actionClicked())
 * @author Rob_2
 *
 */
public class ActionBar extends LinearLayout{
	private LinearLayout containerHome;
	private LinearLayout containerTitle;
	private LinearLayout containerRight;

	public static final int CONTAINER_HOME = 1;
	public static final int CONTAINER_TITLE = 2;
	public static final int CONTAINER_RIGHT = 3;

	private static final LayoutParams LAYOUT_PARAMS_GENERIC = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);
	private static final LayoutParams LAYOUT_PARAMS_TITLE = new LayoutParams(0, LayoutParams.FILL_PARENT, 1);
	private LayoutParams layout_params_divider;
	private int DEFAULT_BACKGROUND_RESOURCE = R.drawable.actionbar_default_background;
	private static Drawable DEFAULT_BACKGROUND_DRAWABLE;
	private int pxFor5DP;
	private int pxFor2DP;
	private int pxFor45DP;
	private int pxFor1DP;
	@SuppressWarnings("unused")
	private int pxFor10DP;
	private int pxFor35DP;
	private ViewGroup.LayoutParams layout_params_actionbar;

	public ActionBar(Context context) {
		super(context);
		loadRoutine();
	}

	public ActionBar(Context context, AttributeSet attrs) {
		super(context, attrs);
		loadRoutine();
	}

	private void loadRoutine() {

		if (DEFAULT_BACKGROUND_DRAWABLE == null) {
			DEFAULT_BACKGROUND_DRAWABLE = getResources().getDrawable(DEFAULT_BACKGROUND_RESOURCE);			
		}
		setBackgroundDrawable(DEFAULT_BACKGROUND_DRAWABLE);

		// configure dimensions
		pxFor1DP = UtilScreen.getPixelForDip(getContext(), 1);
		pxFor2DP = UtilScreen.getPixelForDip(getContext(), 2);
		pxFor5DP= UtilScreen.getPixelForDip(getContext(), 5);
		pxFor10DP = UtilScreen.getPixelForDip(getContext(), 10);
		pxFor35DP = UtilScreen.getPixelForDip(getContext(), 35);
		pxFor45DP = UtilScreen.getPixelForDip(getContext(), 45);
		layout_params_divider = new LayoutParams(pxFor2DP, pxFor35DP);
		layout_params_actionbar = new ViewGroup.LayoutParams(LayoutParams.FILL_PARENT, pxFor45DP);

		// padding is used because there are corners in the default drawable
		setPadding(pxFor5DP, pxFor2DP, pxFor5DP, pxFor2DP);
		setLayoutParams(layout_params_actionbar);


		setContainers();

		// TODO make this neater: 
		loadHomeButton();
	}

	private void loadHomeButton() {
		
		ActionImage home = new ActionImage(getContext()) {
			public void actionClicked() {
				Intent launchHomeScreen = new Intent(getContext(), Launch.class);
				launchHomeScreen.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
				getContext().startActivity(launchHomeScreen);				
			}
		};
		home.setBackgroundResource(R.drawable.ic_action_home);
		addAction(home, ActionBar.CONTAINER_HOME);
	}

	/**
	 * this handles ensuring we have the correct context for any views we build.
	 */
	private void setContainers() {

		containerHome = new LinearLayout(getContext());
		containerHome.setGravity(Gravity.CENTER_VERTICAL);
		addView(containerHome, LAYOUT_PARAMS_GENERIC);
		refreshContainer(containerHome);

		containerTitle = new LinearLayout(getContext());
		containerTitle.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
		containerTitle.setPadding(pxFor5DP, 0, 0, 0);
		addView(containerTitle, LAYOUT_PARAMS_TITLE);
		refreshContainer(containerTitle);

		containerRight = new LinearLayout(getContext());
		containerRight.setGravity(Gravity.CENTER_VERTICAL);
		addView(containerRight, LAYOUT_PARAMS_GENERIC);
		refreshContainer(containerRight);
	}
	private void refreshContainer(LinearLayout container) {
		if (container != null) {
			int visibility = (container.getChildCount() >=1) ? View.VISIBLE : View.GONE;
			container.setVisibility(visibility);
		}
	}

	/**
	 * this will take the action passed in and place in the appropriate container
	 * @param toAdd
	 * @param addToContainer
	 */
	public void addAction(Action toAdd, int addToContainer) {
		LinearLayout container = getContainer(addToContainer);
		if (container == null){
			throw new IllegalArgumentException("you have provided an unknown container to add to. try again");
		} else if (toAdd == null) {
			throw new IllegalArgumentException("you have to provide an action to add");
		}

		if (isAddToContainerAllowed(addToContainer, container) == false) {
			// TODO: ADD AN OVERFLOW CONTAINER
			return;
		}

		switch (addToContainer) {
		case CONTAINER_HOME:	
			container.addView(toAdd.getView());
			container.addView(getNewDivider());
			break;
		case CONTAINER_RIGHT: 
			container.addView(getNewDivider());
			container.addView(toAdd.getView());
			break;
		case CONTAINER_TITLE: 
			container.addView(toAdd.getView(), container.getChildCount());
		default:
		}
		refreshContainer(container);
	}

	private boolean isAddToContainerAllowed(int addToContainer, LinearLayout container) {
		switch (addToContainer) {
		case CONTAINER_HOME: 
		case CONTAINER_TITLE:
			return container.getChildCount() == 0;
		case CONTAINER_RIGHT:
			return container.getChildCount() <= 4;
		}
		return false;
	}

	private View getNewDivider() {
		int[] colours = new int[3];
		colours[0] = getResources().getColor(android.R.color.transparent);
		colours[1] = getResources().getColor(android.R.color.black);
		colours[2] = getResources().getColor(android.R.color.transparent);
		GradientDrawable customGradient = new GradientDrawable(Orientation.TOP_BOTTOM, colours);
		customGradient.setShape(GradientDrawable.RECTANGLE);
		
		View divider = new View(getContext());
		LayoutParams dividerParams = new LayoutParams(layout_params_divider);
		int left = pxFor5DP;
		int right = pxFor5DP;
		dividerParams.setMargins(left, 0, right, 0);
		divider.setLayoutParams(dividerParams);
		divider.setBackgroundDrawable(customGradient);

		return divider;
	}

	private LinearLayout getContainer(int directionToAdd) {
		switch (directionToAdd) {
		case CONTAINER_HOME: return containerHome;
		case CONTAINER_RIGHT: return containerRight;
		case CONTAINER_TITLE: return containerTitle;
		}
		return null;
	}


	public static abstract class ActionButton implements Action {
		private Button button;

		public ActionButton(Context context) {
			button = new Button(context);
			button.setOnClickListener(new OnClickListener() {
				public void onClick(View v) { actionClicked(); }
			});
		}
		public void setBackgroundResource(int imageResource) {
			button.setBackgroundResource(imageResource);
			button.setGravity(Gravity.CENTER);
		}		
		public void setTextColour(int colourResource) { button.setTextColor(colourResource); }
		public void setText(int stringResource) { button.setText(stringResource); }
		public void setText(String text) { button.setText(text); }
		public View getView() { return button; }
		public void setGravity(int gravity) { button.setGravity(gravity); }
	}

	public static abstract class ActionText implements Action {
		private TextView textview;

		public ActionText(Context context) {
			textview = new TextView(context);
			textview.setOnClickListener(new OnClickListener() {
				public void onClick(View v) { actionClicked(); }
			});
		}
		public void setBackgroundResource(int imageResource) { }

		public void setTextColour(int colourResource) { textview.setTextColor(colourResource); }
		public void setText(int stringResource) { textview.setText(stringResource); }
		public void setText(String text) { textview.setText(text); }
		public View getView() { return textview; }
		public void setGravity(int gravity) { textview.setGravity(gravity); }
	}


	public static abstract class ActionImage implements Action {
		private ImageView image;

		public ActionImage(Context _context) {
			image = new ImageView(_context);
			image.setOnClickListener(new OnClickListener() {
				public void onClick(View v) { actionClicked(); }
			});
		}
		public void setBackgroundResource(int imageResource) {
			image.setBackgroundResource(imageResource);
			image.setScaleType(ScaleType.CENTER_INSIDE);
		}
		public View getView() {
			if (image == null) return null;
			return image;
		}
		public void setTextColour(int colourResource) { }
		public void setText(int stringResource) { }
		public void setText(String text) { }
		public void setGravity(int gravity) { }
	}

	public interface Action {
		void actionClicked();
		void setTextColour(int colourResource);
		void setText(int stringResource);
		void setText(String text);
		void setBackgroundResource(int imageResource);
		void setGravity(int gravity);
		View getView();
	}
}